'''
Created on 16/10/2011

@author: nacho
'''

from threading import Thread
from pcCpu import PC
import time




class CPU(Thread):
    '''
    classdocs
    '''



    def __init__(self, os, mmu):
        '''
        Constructor
        '''
        Thread.__init__(self)
        self.os = os
        self.mmu = mmu
        self.executing = True
        self.pc = PC(0,0,0)
        self.registers = {}
        
        
    def run(self):
        
        
        self.startRunning()
        
        while self.isExecuting() and self.os.runningMode():
            
            instruction = self.mmu.read(self.pc.processID(), self.pc.instrNumber())
            
            if instruction is None: #Pregunto si no hay instruccion
                
                print("No hay instruccion")
                #self.os.noInstruction(self.pc.processID())
                
            elif instruction.__class__ == int :
                
                
                self.os.nextInstruction(self.pc.processID(), self.pc.instrNumber())
                
            elif instruction.needCPU():
                
                while not instruction.isFinished() :
                    print("Ejecutando Instruccion")
                    instruction.execute(self)
                    self.os.click()
                   
                    
                if instruction.isFinished():
                    print("Se ejecuto la instruccion " + instruction.exe().__name__)
                   
                    self.os.nextInstruction(self.pc.processID(), self.pc.instrNumber())
                    
                    
            elif not instruction.needCPU() :
                print("Instruccion de IO")
                self.os.ioInstruction(self.pc.processID())
            
            
               
                
            else:
                print("No hay instruccion 2")
                self.os.noInstruction(self.pc.processID())
                
        time.sleep(0.1)
                    
            
        
    def runPCB(self, pid, instrNumber):
        
        
        
        self.pc.setPID(pid)
        self.pc.setInstrNumber(instrNumber)
        self.run()
        
        
    def fullRun(self, pid):
         
        instrNum = self.os.instrNumber(pid)
        self.runPCB(pid, instrNum)
           

        
    def startRunning(self):
        
        self.executing = True
        
    def stopRunning(self):
        
        self.executing = False
        
        
    def isExecuting(self):
        
        return self.executing
    
    ##REGISTERS##
    
    def setVariable(self, name, value):
        
        dire = self.mmu.allocateRegister(value)
        self.registers[name] = dire
        
    def getVariable(self, name):
        
        try:
            value = self.registers[name]
        except KeyError:
            
            print("Undefined Variable")
            
        else:
            
            return self.mmu.readRegister(value)
        
        
        
    
    